//
//  EVEAPIDownloader.m
//  EVE Mac Suite
//
//  Created by Vadim Lozko on 2/7/09.
//  Copyright 2009 __Vadim__. All rights reserved.
//

#import "EVEAPIDownloader.h"
#import "EVEAPIDownloaderRequest.h"


@implementation EVEAPIDownloader

@synthesize delegate, activeConnection;

+(EVEAPIDownloader*)sharedDownloader
{
	static EVEAPIDownloader *sharedDownloader;
	
	@synchronized(self)
	{
		if (!sharedDownloader)
		{
			sharedDownloader = [[EVEAPIDownloader alloc] init];
		}
		
		return sharedDownloader;
	}
	return nil;
}

-(id)init
{
	if(self = [super init])
	{
		requestQueue = [[NSMutableArray alloc] init];
	}
	return self;
}

-(void)dealloc
{ 
	[requestQueue release];
	self.activeConnection = nil;
	[super dealloc];
}

-(NSString*)postStringForUserID:(NSString*)userID 
						 apiKey:(NSString*)apiKey 
					characterID:(NSString*)characterID
					  pixelSize:(NSString*)pixelSize
{
	NSMutableString* postString = [NSMutableString string];
	if(pixelSize)
	{
		[postString appendFormat:@"?s=%@",pixelSize];
		[postString appendFormat:@"&c=%@",characterID];
	} else {
		if(userID)
			[postString appendFormat:@"&userID=%@", userID];
		if(apiKey)
			[postString appendFormat:@"&apiKey=%@", apiKey];
		if(characterID)
			[postString appendFormat:@"&characterID=%@", characterID];
	}
	return postString;
}

-(NSString*)server
{
	return [[EMSGeneralUtils urlConstants] objectForKey:@"APIServer"];
}

-(void)popQueue
{
	if([requestQueue count] > 0)
	{
		[requestQueue removeObjectAtIndex:0];
	} else {
#ifdef DEBUG
		NSLog(@"Pop called with 0 objects in queue");
#endif
	}
}

-(void)performDownloadWithRequest:(NSURLRequest*)request
{
	if([requestQueue count] > 0)
	{
		NSURLConnection* newConnection = [[NSURLConnection alloc] initWithRequest:request delegate:self];
		self.activeConnection = newConnection;
		[newConnection release];
		receivedData = [[NSMutableData alloc] init];
		[self.activeConnection start];
	}
}
/*
-(void)performDownloadWithRequest:(NSURLRequest*)request
{
	if([requestQueue count] > 0)
	{
		NSError* error = nil;
		id handler = [[requestQueue objectAtIndex:0] handler];
		NSAutoreleasePool* downloaderPool = [[NSAutoreleasePool alloc] init];
		NSURLResponse* response = [[[NSURLResponse alloc] initWithURL:[request URL] MIMEType:@"text/xml" expectedContentLength:-1 textEncodingName:nil] autorelease];
		NSData* downloadedData = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&error];
		if(error)
		{
			if([handler respondsToSelector:@selector(downloadRequestDidFailWithError:)])
			{
				[handler performSelectorOnMainThread:@selector(downloadRequestDidFailWithError:) withObject:error waitUntilDone:YES];
			}
			[self performSelectorOnMainThread:@selector(popQueue) withObject:nil waitUntilDone:YES];
		} else{
			NSXMLDocument* requestedDoc = [[NSXMLDocument alloc] initWithData:downloadedData options:NSXMLDocumentTidyHTML error:&error];
			if(error)
			{
				NSString* stringFromData = [[NSString alloc] initWithData:downloadedData encoding:NSUTF8StringEncoding];
				//Implement true error handling
				NSLog(@"Error: %@", error);
				NSLog(@"Received String: %@", stringFromData);
			} else {
				[self performSelectorOnMainThread:@selector(popQueue) withObject:nil waitUntilDone:YES];
				if([handler respondsToSelector:@selector(downloadRequestDidFinishForXMLDoc:)])
				{
					[handler performSelectorOnMainThread:@selector(downloadRequestDidFinishForXMLDoc:) withObject:requestedDoc waitUntilDone:NO];
				}
				
			}
		}
		[self performSelectorOnMainThread:@selector(performNextRequest) withObject:nil waitUntilDone:NO];
		[downloaderPool release];
	}
}*/

-(void)performNextRequest
{
	if([requestQueue count] > 0)
	{
		EVEAPIDownloaderRequest* nextRequest = [requestQueue objectAtIndex:0];
		NSString* requestType = [nextRequest type];
		NSDictionary* info = [nextRequest info];
		NSString* requestString = [NSString stringWithFormat:@"%@%@",
									   [self server],[[EMSGeneralUtils urlConstants] objectForKey:requestType]];
		NSMutableURLRequest* request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:requestString]];
		if(info)
		{
			NSString* postString = [self postStringForUserID:[info objectForKey:CHAR_INFO_DICT_USERID] 
													  apiKey:[info objectForKey:CHAR_INFO_DICT_APIKEY] 
												 characterID:[info objectForKey:CHAR_INFO_DICT_CHARID]
												   pixelSize:[info objectForKey:CHAR_INFO_DICT_PIXELSIZE]];
			NSData* postStringData = [NSData dataWithBytes:[postString UTF8String] length:[postString length]];
			[request setHTTPMethod:@"POST"];
			[request setHTTPBody:postStringData];
		}
		//[NSThread detachNewThreadSelector:@selector(performDownloadWithRequest:) toTarget:self withObject:request];
		[self performDownloadWithRequest:request];
	}
}

-(void)performAPIDownloadRequest:(EVEAPIDownloaderRequest*)request
{
	[requestQueue addObject:request];
	if([requestQueue count] == 1)
	{
		[self performNextRequest];
	}
}

-(void)cancelDownload
{
	if(self.activeConnection)
	{
		[self.activeConnection cancel];
		[receivedData release];
		[requestQueue removeAllObjects];
		self.activeConnection = nil;
	}
}

#pragma mark DelegateMethods

-(void)connection:(NSURLConnection*)connection didReceiveResponse:(NSURLResponse*)response
{
	
}

-(void)connection:(NSURLConnection*)connection didReceiveData:(NSData*)data
{
	[receivedData appendData:data];
}

- (void)connection:(NSURLConnection*)connection didFailWithError:(NSError*)error
{
#ifdef DEBUG
	NSLog(@"Connection error: %@", [error localizedDescription]);
#endif
	[self popQueue];
	[self performNextRequest];
	[receivedData release];
}	

- (void)connectionDidFinishLoading:(NSURLConnection*)connection
{
	self.activeConnection = nil;
	NSError* error = nil;
	NSXMLDocument* requestedDoc = [[NSXMLDocument alloc] initWithData:receivedData options:NSXMLDocumentTidyHTML error:&error];
	if(error)
	{
		NSString* stringFromData = [[NSString alloc] initWithData:receivedData encoding:NSUTF8StringEncoding];
		NSLog(@"Error: %@", [error localizedDescription]);
		NSLog(@"Received String: %@", stringFromData);
		[stringFromData release];
	} else {
		[receivedData release];
		id handler = [[requestQueue objectAtIndex:0] handler];
		[handler downloadRequestDidFinishForXMLDoc:requestedDoc];
		[requestedDoc release];
		[self popQueue];
		
		[self performNextRequest];
		//[self performSelector:@selector(performNextRequest) withObject:nil afterDelay:.1];
		
	}
}

@end
